// ==UserScript==
// @name         linux.do多功能脚本
// @namespace
// @version      2024-10-01
// @description  1. 查看/不看回复 2. 展开/折叠回复 3. 显示楼层 4. 禁用视频自动播放 5. 预览界面
// @author       Jason+马克思+神奇的哆啦z梦
// @match        https://linux.do/*
// @match        https://meta.appinn.net/t/topic/*
// @icon
// @grant         GM_registerMenuCommand
// @grant         GM_unregisterMenuCommand
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';
    //by Jason

    // 简化对localStorage的访问
    const storage = {
        set: (key, value) => window.localStorage.setItem(key, value),
        get: (key, defaultValue) => window.localStorage.getItem(key) || defaultValue,
    };


    GM_registerMenuCommand("查看回复", () => createToggleButton("off"));
    GM_registerMenuCommand("不看回复", () => createToggleButton("on"));
    // 创建并配置按钮
    function createToggleButton(status) {

        storage.set("hide_replies", status);
        toggleRepliesVisibility(1); //立即应用显示设置

        /**
        if (document.getElementById("toggleRepliesVisibilityBtn")) {
            // 如果按钮已存在，则无需重复创建
            return;
        }
        const btn = document.createElement("button");
        btn.id = "toggleRepliesVisibilityBtn";
        btn.textContent = storage.get("hide_replies", "off") === "on" ? '查看回复' : '不看回复';
        btn.onclick = function() {
            const currentState = storage.get("hide_replies", "off");
            const newState = currentState === "on" ? "off" : "on";
            btn.textContent = newState === "on" ? '查看回复' : '不看回复';
            storage.set("hide_replies", newState);
            toggleRepliesVisibility(); //立即应用显示设置
        };
        // 设置按钮样式
        // btn.style.backgroundColor = "#555";
        // btn.style.color = "#FFF";
        // btn.style.border = "none";
        // btn.style.padding = "10px 20px";
        // btn.style.margin = "10px";
        // btn.style.borderRadius = "5px";
        // btn.style.cursor = "pointer";
        btn.className = "btn btn-icon-text btn-default";

        // 添加按钮到页面特定位置
        const controlsContainer = document.querySelector(".timeline-footer-controls");
        if (controlsContainer) {
            controlsContainer.appendChild(btn);
        }
        */
    }

    var replylength = 0
    // 根据设置隐藏或显示回复帖子
    function toggleRepliesVisibility(isOprate = 0) {
        const isHidden = storage.get("hide_replies", "off") === "on";
        const posts = document.querySelectorAll(".topic-post");
        if (replylength != posts.length || isOprate) {
            posts.forEach(post => {
                //当前楼是否是回复其他人
                const hasReply = post.querySelector(".reply-to-tab") !== null;
                //是否有回复
                const hasReply2 = post.querySelector("nav.post-controls .show-replies") !== null;
                post.style.display = isHidden && hasReply && !hasReply2 ? 'none' : '';
                // console.log("隐藏或显示回复帖子:", posts.length);
            });
            //显示楼层
            showFloor(posts)
        }
        replylength = posts.length;

    }

    //by linux.do增加插件

    GM_registerMenuCommand("展开回复", () => toggleReplyVisibility("on"));
    GM_registerMenuCommand("折叠回复", () => toggleReplyVisibility("off"));
    function toggleReplyVisibility(status) {
        storage.set("collapse_replies", status);
    }
    const replyButtonSelector = "nav.post-controls .show-replies";
    var pollinglength2 = 0
    function clickReplyButtons() {
        const isCollapse = storage.get("collapse_replies", "off") === "on";
        if (isCollapse) {
            var le = document.querySelectorAll(".post-stream .topic-post");
            if (pollinglength2 != le.length) {
                pollinglength2 = le.length;
                const replyButtons = document.querySelectorAll(replyButtonSelector);
                replyButtons.forEach(button => {
                    button.click();  // 模拟点击事件
                    // console.log("点击了回复按钮:", replyButtons.length);
                });
            }

        }
    }

    //禁用自动播放
    function disableAutoPlay() {
        // console.log("禁用自动播放搜索调用");
        document.querySelectorAll('iframe, video').forEach((element) => {
            // console.log("禁用自动播放搜索:", element.length);

            let src = element.getAttribute('src');

            // 检查 src 是否存在
            if (src) {
                // 检查是否已有 autoplay=false
                if (!src.includes('autoplay=false')) {
                    // 检查是否已有 autoplay 参数
                    if (src.includes('autoplay=')) {
                        // 如果存在，替换为 autoplay=false
                        src = src.replace(/autoplay=[^&]*/, 'autoplay=false');
                    } else {
                        // 如果不存在，添加 autoplay=false
                        const separator = src.includes('?') ? '&' : '?';
                        src += `${separator}autoplay=false`;
                    }

                    // 更新 src 属性
                    element.setAttribute('src', src);
                }
            }

            // 针对 video 标签设置 autoplay 属性为 false
            if (element.tagName.toLowerCase() === 'video' && element.autoplay) {
                element.autoplay = false;
            }
        });
    }

    //显示楼层
    function showFloor(posts) {
        // console.log("显示楼层搜索调用");
        posts.forEach(post => {
            const article = post.querySelector('article');
            if (article) {
                const num = article.id.replace(/^post_/, "");  // 获取文章的ID并去掉 "post_"

                // 如果尚未添加楼层标识，添加到 post-infos 中
                if (!post.querySelector('.linuxfloor')) {
                    const postInfos = post.querySelector('.post-infos');
                    if (postInfos) {
                        const floorSpan = document.createElement('span');
                        floorSpan.className = 'linuxfloor';
                        floorSpan.textContent = `#${num}`;
                        postInfos.appendChild(floorSpan);
                    }
                }
            }
        });
    }

    //预览帖子
    let previousTopicCount = 0;
    // let previousPostCount = 0;
    function previewTopic() {
        // console.log("预览帖子搜索调用");
        let trs = document.querySelectorAll(".topic-list-body tr")
        const topicCount = trs.length;
        // const postCount = document.querySelectorAll(".post-stream .topic-post").length;
        if (topicCount !== previousTopicCount) {
            previousTopicCount = topicCount;
            //创建背景
            previousTopic();
            setClick();
            //过滤帖子
            filterTopic(trs);
        }

        // if (postCount !== previousPostCount) {
        //     previousPostCount = postCount;
        //     setClick();
        // }
    }

//过滤帖子
    let filterTexts = GM_getValue('filterTitles', []);
    let filterUsers = GM_getValue('filterUsers', []); // 新增屏蔽发帖人
    function filterTopic(trs) {
        trs.forEach((tr, index) => {
            if (tr.style.display === 'none') return; // Skip if already hidden

            let isFilter = false;
            let aDiv = tr.querySelector(".title");

            // Filter titles
            if (aDiv) {
                let title = aDiv.textContent.toLowerCase();
                isFilter = filterTexts.some(text => {
                    // 检查是否是正则表达式格式 (以/开头且以/结尾)
                    if (text.startsWith('/') && text.endsWith('/')) {
                        try {
                            // 提取正则表达式内容并创建RegExp对象
                            const regexPattern = text.substring(1, text.length - 1);
                            const regex = new RegExp(regexPattern, 'i'); // 使用i标志忽略大小写
                            return regex.test(title);
                        } catch (e) {
                            // 如果正则表达式无效，则使用普通文本匹配
                            return title.includes(text.toLowerCase());
                        }
                    } else {
                        // 普通文本匹配
                        return title.includes(text.toLowerCase());
                    }
                });
            }

            // Filter users
            if (!isFilter) {
                let posterLink = tr.querySelector(".posters a");
                let username = posterLink ? posterLink.getAttribute("href").split("/u/")[1] : "";

                if (username) {
                    isFilter = filterUsers.some(user => username.toLowerCase() === user.toLowerCase());
                }
            }

            // Hide or show based on filtering
            tr.style.display = isFilter ? (index !== trs.length - 1 ? 'none' : '') : '';
        });
    }

    // 添加设置屏蔽菜单
    GM_registerMenuCommand("设置屏蔽", showFilterSettings);

    // 添加设置弹框相关函数
    function showFilterSettings() {
        const dialog = document.createElement('div');
        dialog.className = 'filter-settings-dialog';
        dialog.innerHTML = `
            <div class="filter-settings-content">
                <h3>屏蔽设置</h3>
                <div class="filter-section">
                    <label>屏蔽标题(每行一个):</label>
                    <textarea id="filterTitles">${filterTexts.join('\n')}</textarea>
                </div>
                <div class="filter-section">
                    <label>屏蔽用户(每行一个):</label>
                    <textarea id="filterUsers">${filterUsers.join('\n')}</textarea>
                </div>
                <div class="filter-buttons">
                    <button id="saveFilters">保存</button>
                    <button id="cancelFilters">取消</button>
                </div>
            </div>
        `;

        document.body.appendChild(dialog);

        // 绑定按钮事件
        document.getElementById('saveFilters').onclick = () => {
            const newTitles = document.getElementById('filterTitles').value.split('\n').filter(x => x.trim());
            const newUsers = document.getElementById('filterUsers').value.split('\n').filter(x => x.trim());

            GM_setValue('filterTitles', newTitles);
            GM_setValue('filterUsers', newUsers);

            filterTexts = newTitles;
            filterUsers = newUsers;

            document.body.removeChild(dialog);

            // 重新过滤当前页面
            const trs = document.querySelectorAll(".topic-list-body tr");
            filterTopic(trs);
        };

        document.getElementById('cancelFilters').onclick = () => {
            document.body.removeChild(dialog);
        };
    }

    // 修改过小的内容
    function sizeMotified() {
        document.querySelectorAll("span").forEach((e) => {
            let style = window.getComputedStyle(e);
            let fontSize = parseFloat(style.fontSize);
            // 如果 font-size 低于75%, 则将其设置为75%
            if (fontSize < 16 * 0.75) { // 假设默认字体大小为16px
                e.style.fontSize = "75%";
                e.style.color = "grey";
            }
        });
    };

    //添加上/下一贴按钮
    function addPrevNextBtn() {
        // 获取标题元素
        const titleElement = document.querySelector('.title');
        // 判断是否有上/下一贴按钮
        if (document.querySelector('#myprev-topic-btn') === null) {
            // 创建上一贴按钮
            const prevButton = document.createElement('button');
            prevButton.textContent = '上一贴';
            prevButton.className = 'btn btn-prev';
            prevButton.id = 'myprev-topic-btn';
            prevButton.onclick = function () {
                prevNextTopic(true);
            };
            // 将按钮插入到标题元素右边
            titleElement.appendChild(prevButton);

        }
        if (document.querySelector('#mynext-topic-btn') === null) {
            // 创建下一贴按钮
            const nextButton = document.createElement('button');
            nextButton.textContent = '下一贴';
            nextButton.className = 'btn btn-next';
            nextButton.id = 'mynext-topic-btn';
            nextButton.onclick = function () {
                prevNextTopic(false);
            };
            // 将按钮插入到标题元素右边
            titleElement.appendChild(nextButton);
        }
        navigationBarHeight = getNavigationBarHeight();
    }

    //上一贴下一贴
    function prevNextTopic(isUp) {
        // 确定方向，isUp为true表示向上，-1代表上一个，1代表下一个
        const direction = isUp ? -1 : 1;

        // 获取所有topic行的列表
        const trs = document.querySelectorAll(".topic-list-body tr");
        const emberList = Array.from(trs).filter(tr => {
            return tr.style.display !== 'none';  // 过滤掉 display: none; 的行
        });

        // 查找第一个出现在视口中的元素
        const currentElement = emberList.find(tr => isElementPartiallyInViewport(tr));
        if (!currentElement) {
            return;
        }

        // 获取当前元素的索引位置
        const currentIndex = emberList.indexOf(currentElement);
        // 获取下一个或上一个元素的索引
        let nextIndex = currentIndex + direction;

        // 如果下一个元素存在且需要滚动，找到不是"data-topic-id"前缀的元素
        while (nextIndex >= 0 && nextIndex < emberList.length && !emberList[nextIndex].hasAttribute("data-topic-id")) {
            nextIndex += direction;
        }
        // 如果下一个合法元素存在，则进行滚动
        if (nextIndex >= 0 && nextIndex < emberList.length) {
            const nextElement = emberList[nextIndex];
            window.scrollBy(0, nextElement.getBoundingClientRect().top - navigationBarHeight);
        }
    }
    //获取导航栏高度
    function getNavigationBarHeight() {
        return document.querySelector("#ember3 > div.drop-down-mode.d-header-wrap > header > div > div").offsetHeight;
    }
    let navigationBarHeight = 0;
    //判断元素是否在可视范围内
    function isElementPartiallyInViewport(el) {
        const rect = el.getBoundingClientRect();

        const partiallyInViewport = (
            rect.top < (window.innerHeight || document.documentElement.clientHeight) &&
            rect.bottom > navigationBarHeight + 5
        );

        return partiallyInViewport;
    }



    // 监听页面变化来重新应用显示设置
    function observePageChanges() {
        const observer = new MutationObserver((mutations) => {
            //判断当前页面是否是帖子页面
            const url = window.location.href;
            //帖子内
            if (url.indexOf("linux.do/t/topic/") != -1 || url.indexOf("meta.appinn.net/t/topic/") != -1) {
                //是否显示回复的楼
                toggleRepliesVisibility();
                // 是否展开回复
                clickReplyButtons();
                //禁用自动播放
                disableAutoPlay();
                //修改过小的内容
                //sizeMotified()
            } else if (url.indexOf("linux.do/search") != -1 || url.indexOf("meta.appinn.net/search") != -1) {

            } else {
                previewTopic()
            }

        });

        observer.observe(document.body, { childList: true, subtree: true });
    }

    // 初始化脚本
    function init() {
        if (document.readyState === 'complete') {
            observePageChanges();
            toggleRepliesVisibility(); // 初始应用显示设置
        } else {
            window.addEventListener('load', () => {
                observePageChanges();
                toggleRepliesVisibility();
            });
        }
    }

    init();

    //by 马克思
    //按帖子创建时间排序
    function waitForLoad(callback) {
        var observer = new MutationObserver(function (mutations) {
            if (document.readyState === 'complete') {
                observer.disconnect();
                callback();
            }
        });

        observer.observe(document.documentElement, { childList: true, subtree: true });
    }
    // 等待页面加载完成
    waitForLoad(function () {
        modifyNavigationBar();
        observeDocumentChanges();
    });
    function modifyNavigationBar() {
        var navigationBar = document.querySelector('ul#navigation-bar');
        if (navigationBar) {
            var navigationItems = navigationBar.querySelectorAll('li');
            navigationItems.forEach(function (item) {
                var anchor = item.querySelector('a');
                if (anchor && anchor.textContent.trim() === "最新") {
                    anchor.textContent = "新回复";
                    var newestCreatedElement = document.createElement('li');
                    newestCreatedElement.title = "新发的帖子";
                    newestCreatedElement.id = "ember999";
                    newestCreatedElement.className = "active latest_created ember-view nav-item_latest_created";
                    newestCreatedElement.innerHTML = '<a href="' + anchor.getAttribute('href') + '?order=created" pcked="1">新创建</a>';
                    item.insertAdjacentElement('afterend', newestCreatedElement);
                }
            });
            //添加上/下一贴按钮
            //addPrevNextBtn();
        }
    }

    function observeDocumentChanges() {
        var observer = new MutationObserver(function (mutations) {
            mutations.forEach(function (mutation) {
                if (mutation.type === 'childList' && mutation.target.id === 'navigation-bar') {
                    modifyNavigationBar();
                }
            });
        });

        observer.observe(document.documentElement, { childList: true, subtree: true });
    }

    // 初始化话题预览界面
    function previousTopic() {
        if (document.querySelector(".topicpreview") === null) {
            const topicPreviewDiv = document.createElement("div");
            topicPreviewDiv.className = "topicpreview";
            topicPreviewDiv.style.display = 'none';  // 隐藏初始预览窗口
            topicPreviewDiv.innerHTML = `
        <div class="topicpreview-opacity"></div>
        <div class="topicpreview-container">
          <p style="text-align: center">正在加载中...</p>
        </div>
      `;
            document.body.appendChild(topicPreviewDiv);
        }

        // 为每个话题添加预览按钮
        document.querySelectorAll(".topic-list .main-link a.title").forEach((element) => {
            const id = element.getAttribute("data-topic-id");
            const parent = element.closest(".link-top-line");
            if (parent && parent.querySelector(".topicpreview-btn") === null) {
                const button = document.createElement("button");
                button.className = "btn btn-icon-text btn-default topicpreview-btn";
                button.setAttribute("data-id", id);
                button.textContent = "预览";
                parent.appendChild(button);
                button.addEventListener("click", function () {
                    console.log("点击预览按钮:", this.getAttribute("data-id"));
                    const previewContainer = document.querySelector(".topicpreview-container");
                    const previewOverlay = document.querySelector(".topicpreview");
                    previewOverlay.style.display = "block";  // 显示预览弹窗;
                    const previewId = this.getAttribute("data-id");


                    fetch(`/t/${previewId}.json`)
                        .then((response) => response.json())
                        .then((data) => {

                        const previewData = data;


                        // 更新预览窗口内容
                        previewContainer.innerHTML = `
                  <div class="topicpreview-title">${previewData.title}</div>
                  <p class="topicpreview-date">发帖时间：${formatDate(previewData.created_at)}</p>
                  <div class="topicpreview-content"></div>
                  <p style="text-align: center;">仅显示前 20 条，<a href="/t/topic/${previewId}/">查看更多</a></p>
                `;

                        // 显示每个帖子
                        previewData.post_stream.posts.forEach((post, index) => {
                            const postElement = document.createElement("div");
                            postElement.className = "item";
                            postElement.innerHTML = `
                    <span class="itemfloor">${index + 1}楼</span>
                    <div class="itempost">
                      <div class="itemname">
                        ${post.display_username} <span>${post.username}</span>
                        <div class="itemdate">${formatDate(post.created_at)}</div>
                      </div>
                      ${post.cooked}
                    </div>
                  `;
                            document.querySelector(".topicpreview .topicpreview-content").appendChild(postElement);
                        });

                        // 防止图片点击打开 lightbox
                        setInterval(() => {
                            document.querySelectorAll(".lightbox").forEach((el) => {
                                el.href = "javascript:void(0)";
                            });
                        }, 3000);
                    });
                });
            }
        });
    }
    // 格式化时间函数
    function formatDate(isoString) {
        const date = new Date(isoString);
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, "0");
        const day = String(date.getDate()).padStart(2, "0");
        const hours = String(date.getHours()).padStart(2, "0");
        const minutes = String(date.getMinutes()).padStart(2, "0");
        const seconds = String(date.getSeconds()).padStart(2, "0");
        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    }

    // 设置按钮点击事件，显示预览弹窗
    function setClick() {
        // 点击背景关闭预览
        document.querySelector(".topicpreview-opacity").addEventListener("click", function () {
            document.querySelector(".topicpreview").style.display = "none";
            document.querySelector(".topicpreview-container").innerHTML = `<p style="text-align: center">正在加载中...</p>`;
        });
    }
    GM_addStyle(`
        .topicpreview-btn {
            padding: 4px 12px !important;
            font-size: 14px !important;
            opacity: 0 !important
          }

          .topic-list-item:hover .topicpreview-btn {
            opacity: 1 !important;
          }

          .topicpreview {
            position: fixed;
            top: 0;
            left: 0;
            z-index: 99999;
            width: 100vw;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            display: none;

            .topicpreview-container {
              padding: 30px 0;
              border-radius: 5px;
              width: 100%;
              max-width: 800px;
              overflow-y: auto;
              height: 80vh;
              z-index: 10;
              background: var(--header_background);
              position: absolute;
              left: 50%;
              top: 50%;
              transform: translate(-50%, -50%);

              .topicpreview-title {
                font-size: 22px;
                font-weight: 600;
                padding: 0 30px;
              }

              .topicpreview-date {
                padding: 0 30px;
                color: #666;
              }

              .topicpreview-content {
                &>.item {
                  display: flex;
                  align-items: flex-start;
                  padding: 20px 30px;

                  .itemfloor {
                    width: 50px;
                    text-align: left;
                    font-size: 16px;
                    padding-top: 15px;
                    color: #25b4cf;
                  }

                  .itempost {
                    flex: 1;
                    background: var(--tertiary-low);
                    padding: 15px 15px;
                    border-radius: 10px;
                    font-size: 15px;
                    word-break: break-all;
                    // color: #666;

                    pre code {
                      max-width: 620px;
                    }

                    img {
                      max-width: 100%;
                      max-height: 100%;
                      height: auto;
                    }

                    .itemname {
                      font-size: 16px;
                      color: #8f3a3a;
                      display: flex;
                      justify-content: space-between;
                      align-items: center;

                      span {
                        color: #9e9e9e;
                        margin-left: 20px;
                      }
                    }

                    .itemdate {
                      color: #b9b9b9;
                      font-size: 16px;
                      margin-left: auto;
                    }
                  }
                }
              }
            }
          }

          .topicpreview-opacity {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            opacity: 1;
            background: rgba(0, 0, 0, .6);
            z-index: 9;
          }
      `);

    // 添加样式
    GM_addStyle(`
    .filter-settings-dialog {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0,0,0,0.5);
        z-index: 10000;
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .filter-settings-content {
        background: var(--header_background);
        padding: 20px;
        border-radius: 8px;
        min-width: 400px;
    }

    .filter-section {
        margin: 15px 0;
    }

    .filter-section label {
        display: block;
        margin-bottom: 5px;
    }

    .filter-section textarea {
        width: 100%;
        height: 100px;
        margin-bottom: 10px;
    }

    .filter-buttons {
        text-align: right;
    }

    .filter-buttons button {
        margin-left: 10px;
        padding: 5px 15px;
    }
    `);
})();

